package mammuthus.controller.docker

import net.csdn.modules.http.{ViewType, RestRequest, ApplicationController}
import net.csdn.annotation.rest.{State, BasicInfo, At}
import com.google.inject.Inject
import mammuthus.master.Master
import net.liftweb.{json => SJSon}
import mammuthus.slave.InteractiveShellCommand
import mammuthus.controller.filter.TokenAuthFilter

/**
 * 2/2/15 WilliamZhu(allwefantasy@gmail.com)
 */
class DockerTaskController @Inject()(val akkaMaster: Master) extends ApplicationController with DockerTaskHelper with TokenAuthFilter {

  implicit val formats = SJSon.Serialization.formats(SJSon.NoTypeHints)


  @At(path = Array("/docker/repo"), types = Array(RestRequest.Method.GET, RestRequest.Method.POST))
  @BasicInfo(
    desc = "安装docker 镜像服务",
    state = State.alpha,
    testParams = "?slaves=allwefantasy&operate=install&tomeout=30000",
    testResult = "",
    author = "WilliamZhu",
    email = "allwefantasy@gmail.com"
  )
  def dockerRepo = {
    auth
    akkaMaster.installRepo(param("slaves"), paramAsLong("timeout", InteractiveShellCommand.defaultTimeOut))
  }

  @At(path = Array("/docker/build/agent"), types = Array(RestRequest.Method.GET, RestRequest.Method.POST))
  @BasicInfo(
    desc = "生成包含agent 的docker镜像",
    state = State.alpha,
    testParams = "?slaves=allwefantasy&masterIP=",
    testResult = "",
    author = "WilliamZhu",
    email = "allwefantasy@gmail.com"
  )
  def dockerBuildAgent = {
    auth
    val res = akkaMaster.buildDockerAgent(
      param("slaves"),
      param("agentPort", "5020"),
      param("sourceImage", "centos:centos7"),
      param("targetImage", "mammuthus-agent"),
      paramAsBoolean("skipDownload", false))
    render(SJSon.Serialization.write(res), ViewType.json)
  }

  @At(path = Array("/docker/run"), types = Array(RestRequest.Method.GET, RestRequest.Method.POST))
  @BasicInfo(
    desc = "启动某个镜像，需要填写masterIP，保证该镜像能够找到master",
    state = State.alpha,
    testParams = "?slaves=allwefantasy&imageName=&name=&masterIP=",
    testResult = "",
    author = "WilliamZhu",
    email = "allwefantasy@gmail.com"
  )
  def dockerRun = {
    auth
    val res = akkaMaster.run(param("slaves"),
      param("imageName"), param("name"),
      param("masterIP", "192.168.9.48"),
      param("net", ""),
      paramAsBoolean("setHostname", false),
      params()
    )
    render(SJSon.Serialization.write(res), ViewType.json)
  }

  @At(path = Array("/docker/container/list"), types = Array(RestRequest.Method.GET, RestRequest.Method.POST))
  @BasicInfo(
    desc = "罗列所有容器实例",
    state = State.alpha,
    testParams = "?slaves=allwefantasy&status=running|exited|exception|all&pretty=false&timeFormat=yyyyMMdd-hh:MM:ss",
    testResult = "",
    author = "WilliamZhu",
    email = "allwefantasy@gmail.com"
  )
  def dockerContainerList = {
    auth
    val res = akkaMaster.dockerContainerList(param("slaves")).flatMap {
      f =>
        f.instances.filter {
          instance =>
            val status = instance.status.toLowerCase
            filterStatus(status)
        }
    }.map {
      ist =>
        if (paramAsBoolean("pretty", true)) formatContainerDetail(ist)
        else ist
    }

    render(SJSon.Serialization.write(res), ViewType.json)
  }


  @At(path = Array("/docker/container/start"), types = Array(RestRequest.Method.GET, RestRequest.Method.POST))
  @BasicInfo(
    desc = "罗列所有容器实例",
    state = State.alpha,
    testParams = "?slaves=allwefantasy&id=",
    testResult = "",
    author = "WilliamZhu",
    email = "allwefantasy@gmail.com"
  )
  def dockerContainerStart = {
    auth
    if (isEmpty(param("slaves")) || isEmpty(param("id"))) render(400, "params slaves,id should not be empty")
    val res = akkaMaster.dockerContainerStart(param("slaves"), param("id"))
    render(SJSon.Serialization.write(res), ViewType.json)
  }

  @At(path = Array("/docker/container/stop"), types = Array(RestRequest.Method.GET, RestRequest.Method.POST))
  @BasicInfo(
    desc = "罗列所有容器实例",
    state = State.alpha,
    testParams = "?slaves=allwefantasy&id=",
    testResult = "",
    author = "WilliamZhu",
    email = "allwefantasy@gmail.com"
  )
  def dockerContainerStop = {
    auth
    if (isEmpty(param("slaves")) || isEmpty(param("id"))) render(400, "params slaves,id should not be empty")
    val res = akkaMaster.dockerContainerStop(param("slaves"), param("id"))
    render(SJSon.Serialization.write(res), ViewType.json)
  }

  @At(path = Array("/docker/network/configure"), types = Array(RestRequest.Method.GET, RestRequest.Method.POST))
  @BasicInfo(
    desc = "罗列所有容器实例",
    state = State.alpha,
    testParams = "?slaves=allwefantasy&eth=&gatewayIP=",
    testResult = "",
    author = "WilliamZhu",
    email = "allwefantasy@gmail.com"
  )
  def dockerNetworkConfigure = {
    auth
    if (isEmpty(param("slaves")) || isEmpty(param("eth")) || isEmpty(param("gatewayIP"))) render(400, "params slaves,eth,gatewayIP should not be empty")
    val res = akkaMaster.configHostNetwork(param("slaves"), param("eth"), param("gatewayIP"))
    render(SJSon.Serialization.write(res), ViewType.json)
  }

  @At(path = Array("/docker/container/ip/configure"), types = Array(RestRequest.Method.GET, RestRequest.Method.POST))
  @BasicInfo(
    desc = "罗列所有容器实例",
    state = State.alpha,
    testParams = "?slaves=allwefantasy&eth=&gatewayIP=",
    testResult = "",
    author = "WilliamZhu",
    email = "allwefantasy@gmail.com"
  )
  def dockerContainerIpConfigure = {
    auth
    if (isEmpty(param("slaves")) || isEmpty(param("id")) || isEmpty(param("gatewayIP")) || isEmpty(param("ip"))) render(400, "params slaves,id,br,gatewayIP,ip should not be empty")
    val res = akkaMaster.configDockerIp(param("slaves"), param("brName", "mammuthusbr0"), param("id"), param("ip"), param("gatewayIP"))
    render(SJSon.Serialization.write(res), ViewType.json)
  }

}
